"""
用户登录视图
"""
from django.shortcuts import render, HttpResponse, redirect
from django import forms
from app import models
from app.utils.bootstrap import BootstrapForm, BootstrapModelForm
from app.utils.code import check_code  # 验证码
from app.utils.encrypt import md5
from io import BytesIO  # 用于在内存中生成文件，验证码用

"""
两种实现方式
1.LoginForm 是用Form实现，字段需要自己写
2.LoginModelForm 是用ModelForm实现，字段可以从数据库(models)中获取
"""

"""登录窗体"""


class LoginForm(BootstrapForm):
    username = forms.CharField(
        label='用户名',
        widget=forms.TextInput,
        required=True,  # 必填
    )
    password = forms.CharField(
        label='密码',
        widget=forms.PasswordInput(render_value=True),  # render_value 不清空密码
        required=True,  # 必填
    )
    img_code = forms.CharField(
        label='验证码',
        widget=forms.TextInput,
        required=True,  # 必填
    )

    # 钩子方法，猎取密码的md5值
    def clean_password(self):
        pwd = self.cleaned_data.get('password')
        return md5(pwd)


# 这个类没有用到，因为登录界面就两个输入框 ，简单，所以用Form实现
class LoginModelForm(BootstrapModelForm):
    class Meta:
        models = models.Admin
        fields = ['username', 'password']


""" 用户登录 """


def login(request):
    if request.method == 'GET':
        form = LoginForm()
        return render(request, 'login.html', {'form': form})

    form = LoginForm(data=request.POST)
    if form.is_valid():
        # 验证成功，获取到用户名和密码
        # form.cleaned_data本身是一个字典
        print(form.cleaned_data)

        # 验证码校验
        # 取出用户输入的验证码，并且从cleaned_data字典中删除，确保在数据库验证中不携带验证码
        user_input_imgcode = form.cleaned_data.pop('img_code')
        code = request.session.get('img_code', '')
        if code.upper() != user_input_imgcode.upper():
            form.add_error('img_code', '验证码错误')
            return render(request, 'login.html', {'form': form})

        # 查询数据库中的用户名,没查到返回None
        # models.Admin.objects.filter(username=form.cleaned_data['username'],password=form.cleaned_data['password']).first()
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        if not admin_object:
            # 主动在password下展示错误信息
            form.add_error('password', '用户名或密码错误')
            return render(request, 'login.html', {'form': form})
        # 正确输入
        # 这里就要用到cookie和session的知识了，
        # 1.先生成一个随机字符 2.写入到本地浏览器的cookie中 3.再写入到服务器(网站)的session中
        # 但django帮我们简化成了
        # request.session['info'] = admin_object.username  # 可以存入一个值
        request.session['info'] = {'id': admin_object.id, 'username': admin_object.username}
        # 如果登录成功，session会保存7天，免登录
        request.session.set_expiry(60 * 60 * 24 * 7)
        return redirect('/admin/list')
        # return HttpResponse('提交成功')

    return render(request, 'login.html', {'form': form})


""" 生成图片验证码 """


def image_code(request):
    # 生成图片验证码图像和字符串
    img, code_str = check_code()

    # 把验证码写入到session中
    request.session['img_code'] = code_str
    request.session.set_expiry(60)  # 设置session变量的60s超时

    # 写入内存
    stream = BytesIO()  # 在内存中生成文件
    img.save(stream, 'png')  # 把生成的img验证码写入到内存文件中

    return HttpResponse(stream.getvalue())

    # 4. 写入内存（Python2）
    # import StringIO
    # stream = StringIO.StringIO()
    # img.save(stream, 'png')
    # stream.getvalue()


""" 注销用户 """


def loginout(request):
    request.session.clear()
    return redirect('/login/')
